﻿using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
using AudiPyme.BLL;
using System.IO;
using System.Data;
using AudiPyme.DAL;

namespace AudiPyme.UI
{
    public partial class RelacionesAddAmenVuln : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            int idEmpresa = 0;
            if (!IsPostBack)
            {
                ModeloContainer agenteBD = new ModeloContainer();
                //Número de relaciones seleccionadas actualmente
                int nControlesOn = 0;
                //Cogemos el número total de Amenazas y Vulnerabilidades para dimensionar las estructuras acordes a ellas
                int numeroAmenazas = AmenazasFactory.AmenazasTotales();
                int numeroVulnerabilidades = VulnerabilidadesFactory.VulnerabilidadesTotales();
                //Lista de enteros que almacena que relación Amenaza-Vulnerabilidad ha sido seleccionada
                int[,] Contador = new int[numeroAmenazas, numeroVulnerabilidades];
                //Inicializamos la matriz
                for (int i = 0; i < numeroAmenazas; i++)
                {
                    for (int j = 0; j < numeroVulnerabilidades; j++)
                    {
                        Contador[i, j] = 0;
                    }
                }
                String nombreUsuario = (String)Session["nombreUsuario"];
                if (String.IsNullOrEmpty(nombreUsuario))
                {
                    LblInsertar.Text = "No se recogio el usuario";
                    LblInsertar.Visible = true;
                }
                else
                {
                    idEmpresa = UsuariosFactory.EmpresaUsuario(nombreUsuario);
                }
                if (idEmpresa != 0)
                {
                    //Vemos si la empresa tiene relaciones anteriormente cargadas
                    IQueryable<InstanciaAmenazasVulnerabilidades> relaciones = from i in agenteBD.InstanciaAmenazasVulnerabilidadesEstablecer
                                                                               where i.IdEmpresa == idEmpresa
                                                                               select i;
                    int NumeroRelaciones = relaciones.Count();
                    //Si no tiene la empresa relaciones anteriormente cargadas
                    if (NumeroRelaciones == 0)
                    {
                        //Mostramos todas las relaciones de la base de datos
                        var labels = from m in agenteBD.Matriz_AmenazasVulnerabilidadesEstablecer
                                     join a in agenteBD.AmenazasEstablecer on m.IdAmenaza equals a.IdAmenaza
                                     join v in agenteBD.VulnerabilidadesEstablecer on m.IdVulnerabilidad equals v.IdVulnerabilidad
                                     orderby a.IdAmenaza, v.IdVulnerabilidad
                                     select new { a.IdAmenaza, a.Amenaza, v.IdVulnerabilidad, v.Vulnerabilidad };
                        GridView1.DataSource = labels;
                        DataBind();

                    }
                    //Si la empresa ya tiene relaciones anteriormente cargadas
                    else
                    {
                        var subquery = from i in agenteBD.InstanciaAmenazasVulnerabilidadesEstablecer
                                       where i.IdEmpresa == idEmpresa
                                       select i.IdAmenaza;
                        var subquery2 = from i in agenteBD.InstanciaAmenazasVulnerabilidadesEstablecer
                                        where i.IdEmpresa == idEmpresa
                                        select i.IdVulnerabilidad;
                        //Recogemos las relaciones Amenaza-Vulnerabilidad que hay en la BD y la volcamos en el GridView
                        var labels = from m in agenteBD.Matriz_AmenazasVulnerabilidadesEstablecer
                                     join a in agenteBD.AmenazasEstablecer on m.IdAmenaza equals a.IdAmenaza
                                     join v in agenteBD.VulnerabilidadesEstablecer on m.IdVulnerabilidad equals v.IdVulnerabilidad
                                     where !(subquery.Contains(m.IdAmenaza) && subquery2.Contains(m.IdVulnerabilidad))
                                     orderby a.IdAmenaza, v.IdVulnerabilidad
                                     select new { a.IdAmenaza, a.Amenaza, v.IdVulnerabilidad, v.Vulnerabilidad };

                        /*CONSULTA QUE NO FUNCIONABA SI SE TENÍA MÁS DE UNA RELACIÓN DE UNA EMPRESA INTRODUCIDA
                         * var labels = from m in agenteBD.Matriz_AmenazasVulnerabilidadesEstablecer
                                     join a in agenteBD.AmenazasEstablecer on m.IdAmenaza equals a.IdAmenaza
                                     join v in agenteBD.VulnerabilidadesEstablecer on m.IdVulnerabilidad equals v.IdVulnerabilidad
                                     from i in agenteBD.InstanciaAmenazasVulnerabilidadesEstablecer
                                     where !(m.IdAmenaza == i.IdAmenaza && m.IdVulnerabilidad == i.IdVulnerabilidad && i.IdEmpresa == idEmpresa)
                                     orderby a.IdAmenaza, v.IdVulnerabilidad
                                     select new { a.IdAmenaza, a.Amenaza, v.IdVulnerabilidad, v.Vulnerabilidad };
                         */

                        /*
                        var labels = from m in agenteBD.Matriz_AmenazasVulnerabilidadesEstablecer
                                     join a in agenteBD.AmenazasEstablecer on m.IdAmenaza equals a.IdAmenaza
                                     join v in agenteBD.VulnerabilidadesEstablecer on m.IdVulnerabilidad equals v.IdVulnerabilidad
                                     orderby a.IdAmenaza, v.IdVulnerabilidad
                                     select new { a.IdAmenaza, a.Amenaza, v.IdVulnerabilidad, v.Vulnerabilidad };
                         * */
                        GridView1.DataSource = labels;
                        DataBind();
                    }
                    //Inicializamos la estructura que va a almacenar los estados de las relaciones
                    AmenVulnCheck[,] CheckList = new AmenVulnCheck[numeroAmenazas, numeroVulnerabilidades];
                    for (int i = 0; i < numeroAmenazas; i++)
                    {
                        for (int j = 0; j < numeroVulnerabilidades; j++)
                        {
                            CheckList[i, j] = new AmenVulnCheck();
                        }
                    }
                    //Guardamos en variables de sesión
                    Session["CheckList"] = CheckList;
                    Session["Contador"] = Contador;
                    Session["nControlesOn"] = nControlesOn;
                }
                else
                {
                    LblInsertar.Text = "El usuario no está asociado a ninguna Empresa";
                    LblInsertar.Visible = true;
                    BtnInsertar.Visible = false;
                    LblControl.Visible = false;
                }
            }
            //Al ser PostBack creamos la sentencia Linq con las relaciones que aún no ha elegido el usuario
            /*else
            {
                ModeloContainer agenteBD = new ModeloContainer();
                var labels = from m in agenteBD.Matriz_AmenazasVulnerabilidadesEstablecer
                             join a in agenteBD.AmenazasEstablecer on m.IdAmenaza equals a.IdAmenaza
                             join v in agenteBD.VulnerabilidadesEstablecer on m.IdVulnerabilidad equals v.IdVulnerabilidad
                             from i in agenteBD.InstanciaAmenazasVulnerabilidadesEstablecer
                             where !(m.IdAmenaza == i.IdAmenaza && m.IdVulnerabilidad == i.IdVulnerabilidad && i.IdEmpresa == idEmpresa)
                             orderby a.IdAmenaza, v.IdVulnerabilidad
                             select new { a.IdAmenaza, a.Amenaza, v.IdVulnerabilidad, v.Vulnerabilidad };
            }*/
        }

        //Método que se ejecuta al evento de cliquear uno de los checkbox de cualquier relación de la tabla
        protected void CheckBox_Changued(Object sender, EventArgs e)
        {
            //Recuperamos las variables de sesión
            //Recogemos el valor de las relaciones seleccionadas en las otras paginas del GridView
            //con la variable de sesión nControlesOn
            int nControlesOn = (int)Session["nControlesOn"];
            int[,] Contador = (int[,])Session["Contador"];
            AmenVulnCheck[,] CheckList = (AmenVulnCheck[,])Session["Checklist"];
            //Recorremos la página que el gridview muestra
            foreach (GridViewRow row in GridView1.Rows)
            {
                //Recogemos el control CheckBox de cada fila del gridview
                CheckBox Chk = (CheckBox)row.FindControl("CheckBox1");
                //Recogemos el Id de la Amenaza y el Id de la Vulnerabilidad de cada fila
                int IdAmenaza;
                int.TryParse(GridView1.Rows[row.RowIndex].Cells[0].Text, out IdAmenaza);
                int IdVulnerabilidad;
                int.TryParse(GridView1.Rows[row.RowIndex].Cells[2].Text, out IdVulnerabilidad);
                //Si es la primera vez que se elige esa relación, aumentamos el contador
                //y marcamos que esa relación ya está elegida
                if (Chk.Checked == true && Contador[IdAmenaza - 1, IdVulnerabilidad - 1] == 0)
                {
                    if (nControlesOn == 0)
                    {
                        BtnInsertar.Enabled = true;
                    }
                    Contador[IdAmenaza - 1, IdVulnerabilidad - 1] = 1;
                    CheckList[IdAmenaza - 1, IdVulnerabilidad - 1].ValorCheck = true;
                    nControlesOn++;
                }
                //Sino marcamos que la relación no está elegida y actualizamos estructuras
                else if (Chk.Checked == false && Contador[IdAmenaza - 1, IdVulnerabilidad - 1] == 1)
                {
                    Contador[IdAmenaza - 1, IdVulnerabilidad - 1] = 0;
                    CheckList[IdAmenaza - 1, IdVulnerabilidad - 1].ValorCheck = false;
                    nControlesOn--;
                    if (nControlesOn == 0)
                    {
                        BtnInsertar.Enabled = false;
                    }
                }
            }
            //Actualizamos el número de controles elegidos en el label
            LblControl.Text = nControlesOn.ToString();
            //Guardamos en la variable de sesión
            Session["nControlesOn"] = nControlesOn;
        }

        protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            String nombreUsuario = (String)Session["nombreUsuario"];
            int IdEmpresa = UsuariosFactory.EmpresaUsuario(nombreUsuario);
            //Recogemos el array que contiene las relaciones que han sido elegidas 
            int[,] Contador = (int[,])Session["Contador"];
            //Recogemos el array tipado con el valor de las relaciones que han sido elegidas
            AmenVulnCheck[,] CheckList = (AmenVulnCheck[,])Session["Checklist"];
            //Recorremos el Gridview antes de cambiar de página
            foreach (GridViewRow row in GridView1.Rows)
            {
                //Recogemos el control CheckBox de cada fila
                CheckBox Chk = (CheckBox)row.FindControl("CheckBox1");
                //Si está seleccionado
                if (Chk.Checked == true)
                {
                    //Recogemos el IdAmenaza y el IdVulnerabilidad de la fila
                    int IdAmenaza;
                    int.TryParse(GridView1.Rows[row.RowIndex].Cells[0].Text, out IdAmenaza);
                    int IdVulnerabilidad;
                    int.TryParse(GridView1.Rows[row.RowIndex].Cells[2].Text, out IdVulnerabilidad);
                    //Actualizamos el valor de contador
                    //Creamos el objeto AmenContrCheck con los valores y lo insertamos en la lista
                    AmenVulnCheck RelacionCheck = new AmenVulnCheck(IdEmpresa, IdAmenaza, IdVulnerabilidad, true);
                    CheckList[IdAmenaza - 1, IdVulnerabilidad - 1] = RelacionCheck;
                }
                //Si no está seleccionado
                if (Chk.Checked == false)
                {
                    //Recogemos el IdAmenaza e IdVulnerabilidad a de la fila
                    int IdAmenaza;
                    int.TryParse(GridView1.Rows[row.RowIndex].Cells[0].Text, out IdAmenaza);
                    int IdVulnerabilidad;
                    int.TryParse(GridView1.Rows[row.RowIndex].Cells[2].Text, out IdVulnerabilidad);
                    //Actualizamos el valor de contador
                    Contador[IdAmenaza - 1, IdVulnerabilidad - 1] = 0;
                    //Creamos el objeto AmenContrCheck con los valores y lo insertamos en la lista
                    AmenVulnCheck ControlChequeado = new AmenVulnCheck(IdEmpresa, IdAmenaza, IdVulnerabilidad, false);
                }
            }
            //Actualizamos la variable de sesión
            Session["Contador"] = Contador;
            this.GridView1.PageIndex = e.NewPageIndex;
            Session["CheckList"] = CheckList;

            ModeloContainer agenteBD = new ModeloContainer();
            var subquery = from i in agenteBD.InstanciaAmenazasVulnerabilidadesEstablecer
                           where i.IdEmpresa == IdEmpresa
                           select i.IdAmenaza;
            var subquery2 = from i in agenteBD.InstanciaAmenazasVulnerabilidadesEstablecer
                            where i.IdEmpresa == IdEmpresa
                            select i.IdVulnerabilidad;
            //Recogemos las relaciones Amenaza-Vulnerabilidad que hay en la BD y la volcamos en el GridView
            var labels = from m in agenteBD.Matriz_AmenazasVulnerabilidadesEstablecer
                         join a in agenteBD.AmenazasEstablecer on m.IdAmenaza equals a.IdAmenaza
                         join v in agenteBD.VulnerabilidadesEstablecer on m.IdVulnerabilidad equals v.IdVulnerabilidad
                         where !(subquery.Contains(m.IdAmenaza) && subquery2.Contains(m.IdVulnerabilidad))
                         orderby a.IdAmenaza, v.IdVulnerabilidad
                         select new { a.IdAmenaza, a.Amenaza, v.IdVulnerabilidad, v.Vulnerabilidad };
            GridView1.DataSource = labels;
            DataBind();
            //Cargamos el valor de las relaciones que estuvieran seleccionados anteriormente
            AmenVulnCheck controlLista;
            int numeroAmenazas = AmenazasFactory.AmenazasTotales();
            int numeroVulnerabilidades = VulnerabilidadesFactory.VulnerabilidadesTotales();
            for (int i = 0; i < numeroAmenazas; i++)
            {
                for (int j = 0; j < numeroVulnerabilidades; j++)
                {
                    controlLista = CheckList[i, j];
                    foreach (GridViewRow row in GridView1.Rows)
                    {
                        int IdAmenaza;
                        int.TryParse(GridView1.Rows[row.RowIndex].Cells[0].Text, out IdAmenaza);
                        int IdVulnerabilidad;
                        int.TryParse(GridView1.Rows[row.RowIndex].Cells[2].Text, out IdVulnerabilidad);
                        if (IdAmenaza == controlLista.IdAmenaza && IdVulnerabilidad == controlLista.IdVulnerabilidad)
                        {
                            CheckBox Chk = (CheckBox)row.FindControl("CheckBox1");
                            if (controlLista.ValorCheck)
                            {
                                Chk.Checked = true;
                            }
                            else
                            {
                                Chk.Checked = false;
                            }
                        }
                    }
                }
            }
        }

        protected void BtnInsertar_Click(object sender, EventArgs e)
        {
            //Recogemos las variables de sesión
            AmenVulnCheck[,] CheckList = (AmenVulnCheck[,])Session["Checklist"];
            AmenVulnCheck controlLista;
            //Recogemos los limites de la estructura para recorrerla
            int numeroAmenazas = AmenazasFactory.AmenazasTotales();
            int numeroVulnerabilidades = VulnerabilidadesFactory.VulnerabilidadesTotales();
            String nombreUsuario = (String)Session["nombreUsuario"];
            int IdEmpresa = UsuariosFactory.EmpresaUsuario(nombreUsuario);
            for (int i = 0; i < numeroAmenazas; i++)
            {
                for (int j = 0; j < numeroVulnerabilidades; j++)
                {
                    controlLista = CheckList[i, j];
                    //Creamos la estructura
                    if (controlLista.ValorCheck == true)
                    {
                        InstanciaAmenazasVulnerabilidades InstAmenVuln = new InstanciaAmenazasVulnerabilidades();
                        InstAmenVuln.IdEmpresa = IdEmpresa;
                        InstAmenVuln.IdAmenaza = (i + 1);
                        InstAmenVuln.IdVulnerabilidad = (j + 1);
                        ModeloContainer agenteBD = new ModeloContainer();
                        agenteBD.AddToInstanciaAmenazasVulnerabilidadesEstablecer(InstAmenVuln);
                        agenteBD.SaveChanges();
                    }
                }
            }
            Response.Redirect("~/RelacionesAmenVuln.aspx");
        }
    }
}